home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / ncsat.cpt / Telnet2.5 final / tcpip / ser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-08  |  12.3 KB  |  433 lines

  1. /* File:  serial.c
  2. *
  3. *  Developer:        Jim Logan
  4. *  Organization:    Brigham Young University
  5. *  Email:        loganj@byuvax.bitnet
  6. *             loganj@yvax.byu.edu
  7. *
  8. *   Captures incoming data from the active serial port and
  9. *   provides control of serial port characteristics (baud 
  10. *   rate, parity, stop bits, handshaking ... ).
  11. *
  12. */
  13.  
  14. #include <Quickdraw.h>
  15. #include <Devices.h>
  16. #include <Files.h>
  17. #include <Serial.h>
  18. #include <Dialogs.h>
  19. #include <Memory.h>
  20. #include <Packages.h>
  21. #include <Resources.h>
  22. #include <stdio.h>
  23. #include <strings.h>
  24. #include <ToolUtils.h>
  25.  
  26. #include "ConfigRec.h"
  27. #include "whatami.h"
  28. #include "wind.h"
  29.  
  30. #include "Maclook.h"
  31. #include "Slip.h"
  32.  
  33. #define input_size 8192
  34.  
  35. #define SPEED_RESOURCE_ID 23231
  36. #define DATABITS_RESOURCE_ID 23232
  37. #define PARITY_RESOURCE_ID 23233
  38. #define STOPBITS_RESOURCE_ID 23234
  39. #define CHOOSEPORT_RESOURCE_ID 23235
  40. #define HANDSHAKE_RESOURCE_ID 23236
  41.  
  42. extern int numwindows;
  43.  
  44. static ResType
  45.   Setres = 'CNFG';
  46.  
  47. static unsigned char   *minputnam[] = {"\p.ain","\p.bin"};
  48. static unsigned char   *moutputnam[] = {"\p.aout","\p.bout"};
  49.  
  50. #if 0
  51. static unsigned char  *mbtext[] = {
  52.   "\p300 baud","\p600 baud","\p1200 baud","\p1800 baud","\p2400 baud",
  53.   "\p3600 baud","\p4800 baud","\p7200 baud","\p9600 baud",
  54.     "\p19200 baud","\p57600 baud", 0};
  55. static unsigned char  *mdtext[] = {"\p5 data bits","\p6 data bits","\p7 data bits","\p8 data bits", 0};
  56. static unsigned char  *mptext[] = {"\pNo parity","\pOdd parity","\pEven parity", 0};
  57. static unsigned char  *mstext[] = {"\p1 stop bit","\p1.5 stop bits","\p2 stop bits", 0};
  58. static unsigned char  *mPorttext[] = {"\pModem Port","\pPrinter Port", 0};
  59. static unsigned char  *mprottext[] = {"\pNo handshaking","\pXon/Xoff Handshaking", 0};
  60. #endif
  61.  
  62. #if 0
  63. #define baud300 380
  64. #define baud600 189
  65. #define baud1200 94
  66. #define baud1800 62
  67. #define baud2400 46
  68. #define baud3600 30
  69. #define baud4800 22
  70. #define baud7200 14
  71. #define baud9600 10
  72. #define baud19200 4
  73. #define baud57600 0
  74. #define stop10 16384
  75. #define stop15 -32768
  76. #define stop20 -16384
  77. #define noParity 0
  78. #define oddParity 4096
  79. #define evenParity 12288
  80. #define data5 0
  81. #define data6 2048
  82. #define data7 1024
  83. #define data8 3072
  84. #define sPortA 0
  85. #define sPortB 1
  86. #endif
  87.  
  88. static int  mbtable[]     = 
  89.   { baud300, baud600,
  90.     baud1200,baud1800,
  91.     baud2400,baud3600,
  92.     baud4800,baud7200,
  93.     baud9600,baud19200,baud57600};
  94.  
  95. static int  mdtable[]     = {data5,data6,data7,data8};
  96. static int  mptable[]     = {noParity,oddParity,evenParity};
  97. static int  mstable[]     = {stop10,stop15,stop20};
  98. static int  minputnum[] = {-6,-8};    /* File numbers of incoming modem/printer ports */
  99. static int  moutputnum[] = {-7,-9};    /* File numbers of outgoing modem/printer ports */
  100. static unsigned char mramnum[] = {sPortA, sPortB};
  101.  
  102. static SerShk shakies =
  103.   { (char)0,
  104.     (char)0,
  105.     (char)17,    /* "xon" character is control q */
  106.     (char)19,    /* "xoff" character is control s */
  107.     (char)0,
  108.     (char)0,
  109.     (char)1,    /* "fInX" field: enable incoming "xon/xoff" handshaking */
  110.     (char)0};
  111.  
  112. unsigned char 
  113.   SLIP_ip_number[4],
  114.   DTRleaveon = 0x80,
  115.   DTRturnoff = 0x80;
  116.  
  117. short
  118.   serial_scrn=-1,
  119.   slip_connection=0,    /* 0 = serial, 1 = slip */
  120.   mpi,            /* Modem input file refnum */
  121.   mpo,            /* Modem output file refnum */
  122.   mbaud,            /* Port speed         */
  123.   mdata,            /* Port data bits     */
  124.   mparity,          /* Port parity         */
  125.   mport,            /* Port selected     */
  126.   mprot,            /* Port protocol     */
  127.   mstop;            /* Port stop bits     */
  128.  
  129. char 
  130.   *modembuf,
  131.   *incoming;
  132.  
  133. extern WindRec *screens;
  134.  
  135.  
  136. /* Set the program settings from the "CNFG" resource */
  137.  
  138. SetSettings(rp) unsigned short *rp; {
  139. unsigned short *resptr;
  140. unsigned short i;
  141.   resptr = rp;
  142.   mbaud     = *(resptr++);
  143.   mdata     = *(resptr++);
  144.   mparity     = *(resptr++);
  145.   mport     = *(resptr++);
  146.   mprot     = *(resptr++);
  147.   mstop     = *(resptr++);
  148.   i        = *(resptr++);
  149.   SLIP_ip_number[0] = (i >> 8) & 0xff;
  150.   SLIP_ip_number[1] = i & 0xff;
  151.   i        = *(resptr++);
  152.   SLIP_ip_number[2] = (i >> 8) & 0xff;
  153.   SLIP_ip_number[3] = i & 0xff;
  154. }
  155.  
  156.  
  157. /* Get the (program settings) "CNFG" resource */
  158.  
  159. getSettings() {
  160. char **myResource; unsigned short *resptr;
  161. #define    SettingsID    31324
  162.  
  163.     myResource = (char**) GetResource( Setres, SettingsID);
  164.     resptr = (unsigned short*) *myResource;
  165.     SetSettings(resptr);
  166.       ReleaseResource(myResource);
  167. }
  168.  
  169.  
  170. /* Save the program settings in the "CNFG" resource */
  171.  
  172. saveSettings() {
  173. unsigned short     *resptr;
  174. char     **myResource; 
  175. GrafPtr tempPort;
  176.  
  177.   GetPort(&tempPort);
  178.   myResource = (char**) GetResource( Setres, SettingsID);
  179.   resptr = (unsigned short*) *myResource;
  180.   *(resptr++) = mbaud;
  181.   *(resptr++) = mdata;
  182.   *(resptr++) = mparity;
  183.   *(resptr++) = mport;
  184.   *(resptr++) = mprot;
  185.   *(resptr++) = mstop;
  186.   *(resptr++) = (SLIP_ip_number[0] << 8) | SLIP_ip_number[1];
  187.   *(resptr++) = (SLIP_ip_number[2] << 8) | SLIP_ip_number[3];
  188.           
  189.   ChangedResource(myResource);
  190.   WriteResource(myResource);
  191.   ReleaseResource(myResource);
  192.   SetPort(tempPort);
  193. }
  194.  
  195. /* Open a serial port, use the "incoming" buffer, and 
  196.    set "xon/xoff" handshaking on */
  197.  
  198. PortOpen() {
  199. short fstatus,mSettings;
  200. #if 0
  201.   fstatus = RAMSDOpen(mramnum[mport]);
  202. #endif
  203.  
  204.   fstatus = OpenDriver(minputnam[mport],&mpi);
  205.   fstatus = OpenDriver(moutputnam[mport],&mpo);
  206.  
  207.   mSettings = mbtable[mbaud] + mdtable[mdata] + mptable[mparity] + mstable[mstop];
  208.   fstatus = SerReset(mpi,mSettings);
  209.   fstatus = SerReset(mpo,mSettings);
  210.   fstatus = SerSetBuf(mpi,incoming,input_size);    /* Input buffer specification */
  211.   shakies.fInX = (char) mprot;
  212.   fstatus = SerHShake(mpi,&shakies);        /* Handshake parameters */
  213.   Control(mpo,16,(const void *) &DTRleaveon);    /* Leave DTR alone on close */
  214.   Control(mpo,17,(const void *) 0);        /* Enable DTR */
  215. }
  216.  
  217.  
  218. /* Close the serial port */
  219.  
  220. PortClose() {
  221. short fstatus;
  222.   if (mpi != 0) { 
  223.     fstatus = CloseDriver(mpi);
  224.     mpi = 0; 
  225.   }
  226.   if (mpo != 0) { 
  227.     fstatus = CloseDriver(mpo);
  228.     mpo = 0; 
  229.   } 
  230. #if 0
  231.   RAMSDClose(mramnum[mport]);
  232. #endif
  233. }
  234.  
  235.  
  236. /* This function checks to see if there is any data coming into 
  237.    the serial port, and if so captures the data. */
  238.  
  239. DoModem() {
  240. OSErr     mpistatus;    /* mpi is modem.port.in    */
  241. long    fcount,mpicount;
  242. int    fstatus;
  243.  
  244.   if (serial_scrn >= 0) {
  245.     mpistatus = SerGetBuf(mpi, &mpicount);        /* How much data is coming? */
  246.     if ((mpistatus == noErr) && (mpicount > 0)) {    /* Number of characters. */
  247.  
  248.       fcount = mpicount;
  249.       fstatus = FSRead(mpi, &fcount, modembuf);    /* Read all of the data. */
  250.       if (slip_connection)
  251.         SLIPreceive(modembuf, (int) fcount);
  252.       else
  253.         parse(&screens[serial_scrn], modembuf, (int) fcount);
  254. } } }
  255.  
  256.  
  257. /* Paint a wide border around button #1 to indicate which 
  258.    button is the default button */
  259.  
  260. PaintDial(myDialog)     /* Circle OK    item 1    */
  261. DialogPtr myDialog; {
  262. short     item_type;
  263. Handle     item_Handle;  
  264. Rect     item_box; 
  265.  
  266.   SetPort(    myDialog);
  267.   GetDItem(    myDialog,1,&item_type,&item_Handle,&item_box);
  268.   item_box.left--; item_box.top--;    /* TBD:  use InsetRect() */
  269.   item_box.right++; item_box.bottom++;
  270.   PenSize(3,3);
  271.   InsetRect(      &item_box,-3,-3);
  272.   FrameRoundRect( &item_box,16,16);
  273. }
  274.  
  275.  
  276. /* GetDIHandle - return handle value of dialog item */
  277.  
  278. Handle GetDIHandle(theDia,i) DialogPtr theDia;int i; {
  279. short theType;
  280. Handle theHandle;
  281. Rect theRect;
  282.   GetDItem(theDia, i, &theType, &theHandle, &theRect);
  283.   return theHandle;
  284. }
  285.  
  286.  
  287. /* Restrict the value of an integer to between "lo" and "hi" */
  288.  
  289. int BoundsLimitWithWrapAround( vPtr, lo, hi) short *vPtr, lo, hi; {        /* BYU 2.4.15 MPW */
  290.   if( *vPtr < lo) *vPtr = hi;
  291.   else if( *vPtr > hi) *vPtr = lo;
  292.   return( *vPtr);
  293. }
  294.  
  295.  
  296. /* Set the characteristics of the serial port */
  297.  
  298. Setmodem() {
  299. GrafPtr     tempPort;
  300. short     the_item,tbaud,tdata,tparity,tport,tprot,tstop;
  301. DialogPtr myDialog;
  302. unsigned char TEMP_ip_number[4];
  303. Str255 item_text;  
  304.  
  305.   InitCursor();  
  306.   GetPort(&tempPort);
  307. #define MODEM_DLOD_ID    28243
  308.  
  309.   myDialog = GetNewDialog( MODEM_DLOD_ID,(DialogPeek) 0L, (WindowPtr)-1L);  
  310.   PaintDial(myDialog);
  311.  
  312.   GetIndString(item_text,SPEED_RESOURCE_ID,mbaud+1);
  313.   SetIText( GetDIHandle( myDialog, 15),  item_text);
  314.   GetIndString(item_text,DATABITS_RESOURCE_ID,mdata+1);
  315.   SetIText( GetDIHandle( myDialog, 16),  item_text);
  316.   GetIndString(item_text,PARITY_RESOURCE_ID,mparity+1);
  317.   SetIText( GetDIHandle( myDialog, 17),  item_text);
  318.   GetIndString(item_text,STOPBITS_RESOURCE_ID,mstop+1);
  319.   SetIText( GetDIHandle( myDialog, 18),  item_text);
  320.   GetIndString(item_text,CHOOSEPORT_RESOURCE_ID,mport+1);
  321.   SetIText( GetDIHandle( myDialog, 19),  item_text);
  322.   GetIndString(item_text,HANDSHAKE_RESOURCE_ID,mprot+1);
  323.   SetIText( GetDIHandle( myDialog, 20),  item_text);
  324.   sprintf(item_text,"%d.%d.%d.%d", (int) SLIP_ip_number[0], 
  325.     (int) SLIP_ip_number[1], (int) SLIP_ip_number[2],(int) SLIP_ip_number[3]);
  326.   c2pstr((char *) item_text);
  327.   SetIText( GetDIHandle( myDialog, 21),  item_text);
  328.   SelIText( myDialog,21,0,32767);
  329.  
  330.   tbaud = mbaud; tdata = mdata; tparity = mparity; 
  331.   tport = mport; tprot = mprot; tstop = mstop;
  332.   TEMP_ip_number[0] = SLIP_ip_number[0];
  333.   TEMP_ip_number[1] = SLIP_ip_number[1];
  334.   TEMP_ip_number[2] = SLIP_ip_number[2];
  335.   TEMP_ip_number[3] = SLIP_ip_number[3];
  336.   
  337.   do { 
  338.     ModalDialog((long) 0,&the_item); 
  339.     if ((the_item == 3) || (the_item == 4) ) {            /* UP/DOWN tbaud */
  340.       tbaud += ((the_item == 3 /* UP*/) ? 1 : -1);
  341.       BoundsLimitWithWrapAround( &tbaud, 0, 10);
  342.       GetIndString(item_text,SPEED_RESOURCE_ID,tbaud+1);
  343.       SetIText( GetDIHandle( myDialog, 15),  item_text);
  344.     } else if ((the_item == 5) || (the_item == 6)) {    /* UP/DOWN tdata */
  345.       tdata += ((the_item == 5 /* UP*/) ? 1 : -1);     
  346.       BoundsLimitWithWrapAround( &tdata, 0, 3);
  347.       GetIndString(item_text,DATABITS_RESOURCE_ID,tdata+1);
  348.       SetIText( GetDIHandle( myDialog, 16),  item_text);
  349.     } else if ((the_item == 7) || (the_item == 8)) {    /* UP/DOWN tparity */
  350.       tparity += ((the_item == 7 /* UP*/) ? 1 : -1);
  351.       BoundsLimitWithWrapAround( &tparity, 0, 2);
  352.       GetIndString(item_text,PARITY_RESOURCE_ID,tparity+1);
  353.       SetIText( GetDIHandle( myDialog, 17),  item_text);
  354.     } else if ((the_item == 9) || (the_item == 10)) {    /* UP/DOWN tstop */
  355.       tstop += ((the_item == 9 /* UP*/) ? 1 : -1);
  356.       BoundsLimitWithWrapAround( &tstop, 0, 2);
  357.       GetIndString(item_text,STOPBITS_RESOURCE_ID,tstop+1);
  358.       SetIText( GetDIHandle( myDialog, 18),  item_text);
  359.     } else if ((the_item == 11) || (the_item == 12)) {    /* UP/DOWN tport */
  360.       tport += ((the_item == 11 /* UP*/) ? 1 : -1);
  361.       BoundsLimitWithWrapAround( &tport, 0, 1);
  362.       GetIndString(item_text,CHOOSEPORT_RESOURCE_ID,tport+1);
  363.       SetIText( GetDIHandle( myDialog, 19),  item_text);
  364.     } else if ((the_item == 13) || (the_item == 14)) {    /* UP/DOWN tpROt */
  365.       tprot += ((the_item == 13 /* UP*/) ? 1 : -1);
  366.       BoundsLimitWithWrapAround( &tprot, 0, 1);
  367.       GetIndString(item_text,HANDSHAKE_RESOURCE_ID,tprot+1);
  368.       SetIText( GetDIHandle( myDialog, 20),  item_text);
  369.     } else if (the_item == 21) {            /* SLIP IP number */
  370.       GetIText( GetDIHandle( myDialog, 21),  item_text);
  371.       p2cstr((char *) item_text);
  372.       decodeIPnum(item_text,&TEMP_ip_number[0]);
  373.     }
  374.   } while ((the_item != ok) && (the_item != cancel));    /* BYU 2.4.15 MPW */
  375.   
  376.   if (the_item == ok)             /* BYU 2.4.15 MPW - Save temps to theRealThings    */
  377.   {
  378.     PortClose();
  379.     mbaud = tbaud; mdata = tdata; mparity = tparity; 
  380.     mport = tport; mprot = tprot; mstop = tstop;
  381.     SLIP_ip_number[0] = TEMP_ip_number[0];
  382.     SLIP_ip_number[1] = TEMP_ip_number[1];
  383.     SLIP_ip_number[2] = TEMP_ip_number[2];
  384.     SLIP_ip_number[3] = TEMP_ip_number[3];
  385.     saveSettings();
  386.     PortOpen();
  387.   }
  388.   CloseDialog( myDialog); 
  389.   SetPort(tempPort);
  390.   return( the_item);
  391. }
  392.  
  393. write_serial(buffer,nsend) char *buffer; int nsend; {
  394. long byte_count;
  395. int fstatus;
  396.   byte_count = nsend;
  397.   fstatus = FSWrite(mpo,&byte_count,buffer);
  398. }
  399.  
  400. /* Initialize serial i/o */
  401.  
  402. init_serial() {
  403. long mysize;
  404.     serial_scrn = -1;
  405.     getSettings();
  406.     mysize = input_size;
  407.     modembuf = (char *) NewPtr(mysize);
  408.     incoming = (char *) NewPtr(mysize);
  409. }
  410.  
  411. int open_serial(pnum) int pnum; {
  412.   if (serial_scrn < 0) {
  413.     serial_scrn = numwindows;
  414.     PortOpen();                    /* Open the serial port */
  415.     return pnum;
  416.   }
  417.   OtherError((char *) "\pError opening serial port.",(char *) "\pSerial port already open.");        /* BYU serial */
  418.   return -1;
  419. }
  420.  
  421. close_serial() {
  422.   serial_scrn = -1;
  423.   if (mpo != 0) 
  424.     PortClose();
  425. }
  426.  
  427. serial_shut() {
  428.   serial_scrn = -1;
  429.   if (mpo != 0) {
  430.     Control(mpo,16,(const void *) &DTRturnoff);    /* Don't leave DTR alone on close */
  431.     Control(mpo,18,(const void *) 0);        /* Disable DTR */
  432. } }
  433.